package cn.cms.util;

import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

public class SqlUtil {


    public static String getUpdateSqlPart(Object model , String sql) throws NoSuchMethodException, InvocationTargetException, IllegalAccessException, InstantiationException {
        if(model==null){
            return "";
        }
        String modelClass = model.getClass().toString();
        String tableClass = "class " + getUpdateSqlEntity(sql);
        if(!modelClass.equals(tableClass)){
            throw new RuntimeException("Entity does not match the table : Entity is " + model.getClass().toString() + " , SQL is " + sql);
        }
        Field[] field = model.getClass().getDeclaredFields();
        StringBuffer sb = new StringBuffer();
        for (int j = 0; j < field.length; j++) {
            String name = field[j].getName();
            String getMethodName = "get" + name.substring(0, 1).toUpperCase() + name.substring(1);
           // String setMethodName = "set" + name.substring(0, 1).toUpperCase() + name.substring(1);
            String type = field[j].getGenericType().toString();
            Method get = model.getClass().getMethod(getMethodName);
           // Method set = model.getClass().getMethod(setMethodName,field[j].getType());

            if("id".equals(name.trim())){
                continue;
            }

            if (type.equals("class java.lang.String")) {
                String value = (String) get.invoke(model);
                if (!StringUtil.isSpaceOrNull(value)) {
                    sb.append(" , ");
                    sb.append(getSqlColumn(name)+"= '"+value+"'");
                }
            }
            if (type.equals("class java.lang.Integer")) {
                Integer value = (Integer) get.invoke(model);
                if (StringUtil.isNotEmptyOrNull(value)) {
                    sb.append(" , ");
                    sb.append(getSqlColumn(name)+"="+value);
                }
            }
            if (type.equals("class java.lang.Byte")) {
                Byte value = (Byte) get.invoke(model);
                if (StringUtil.isNotEmptyOrNull(value)) {
                    sb.append(" , ");
                    sb.append(getSqlColumn(name)+"="+value);
                }
            }
            if (type.equals("class java.lang.Float")) {
                Float value = (Float) get.invoke(model);
                if (StringUtil.isNotEmptyOrNull(value)) {
                    sb.append(" , ");
                    sb.append(getSqlColumn(name)+"="+value);
                }
            }
            if (type.equals("class java.lang.Double")) {
                Double value = (Double) get.invoke(model);
                if (StringUtil.isNotEmptyOrNull(value)) {
                    sb.append(" , ");
                    sb.append(getSqlColumn(name)+"="+value);
                }
            }
            if (type.equals("class java.lang.Long")) {
                Long value = (Long) get.invoke(model);
                if (StringUtil.isNotEmptyOrNull(value)) {
                    sb.append(" , ");
                    sb.append(getSqlColumn(name)+"="+value);
                }
            }
            if (type.equals("class java.util.Date")) {
                Date value = (Date) get.invoke(model);
                if (StringUtil.isNotEmptyOrNull(value)) {
                    SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
                    String str = sdf.format(value);
                    String sqlDate = "STR_TO_DATE('" + value + "',\"%Y-%m-%d %H:%i:%s\")";
                    sb.append(" , ");
                    sb.append(getSqlColumn(name)+"="+sqlDate);
                }
            }
            if (type.equals("class java.lang.Boolean")) {
                Boolean value = (Boolean) get.invoke(model);
                if (StringUtil.isNotEmptyOrNull(value)) {
                    sb.append(" , ");
                    sb.append(getSqlColumn(name)+"="+value);
                }
            }
            if (type.equals("class java.lang.Character")) {
                Character value = (Character) get.invoke(model);
                if (StringUtil.isNotEmptyOrNull(value)) {
                    sb.append(" , ");
                    sb.append(getSqlColumn(name)+"='"+value+"'");
                }
            }

        }
        return sb.length()>0 ? sb.substring(2) : "";
    }

    public static String getEntityClass(String tableName){
        if(!StringUtil.isSpaceOrNull(tableName)) {
            char[] c = tableName.toCharArray();
            StringBuffer sb = new StringBuffer();
            for (int i = 0; i < c.length; i++) {
                if (i == 0) {
                    sb.append(Character.toString(c[0]).toUpperCase());
                    continue;
                }
                if (c[i] == '_') {
                    sb.append(Character.toString(c[i + 1]).toUpperCase());
                    i++;
                    continue;
                }
                sb.append(Character.toString(c[i]));
            }
            return "cn.heibes.cms.model." + sb.toString();
        }else {
            return "";
        }
    }

    public static String getSelectSqlEntity(String sql) {
      return getEntityClass(getSelectSqlTable(sql));
    }

    public static String getUpdateSqlEntity(String sql) {
      return getEntityClass(getUpdateSqlTable(sql));
    }

    public static String getUpdateSqlTable(String sql) {
        String str = " " + sql.trim();
        if (!str.contains(" update ")) {
            return "";
        }
        sql = removeRedundantSpaces(str);
        return sql.split(" ")[1].trim();
    }

    public static String getSelectSqlTable(String sql) {
        if (!sql.contains(" from ")) {
            return "";
        }
        return sql.split(" from ")[1].trim().split(" ")[0].trim();
    }

    //名字必须按照驼峰原则才能解析
    public static String getSqlColumn(String str) {
        Pattern pattern = Pattern.compile("[A-Z]");
        Matcher matcher = pattern.matcher(str);
        StringBuffer sb = new StringBuffer();
        while (matcher.find()) {
            matcher.appendReplacement(sb, "_" + matcher.group().toLowerCase());
        }
        matcher.appendTail(sb);
        return sb.toString();
    }

    public static ArrayList<String> getEntityFields(String model) {
        ArrayList<String> list = new ArrayList<>();
        try {
            Class clzz = Class.forName(model);
            Field[] fields = clzz.getDeclaredFields();
            for (int i = 0; i <fields.length ; i++) {
                list.add(fields[i].getName());
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        return list;
    }

    public static String removeRedundantSpaces(String str){
        if(StringUtil.isSpaceOrNull(str)){
            return "";
        }else {
            Pattern p = Pattern.compile("\\s+");
            Matcher m = p.matcher(str);
            return  m.replaceAll(" ").trim();
        }
    }

}
